package school;


import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import school.course.Course;

public class StudentCourseList {
	
	List<StudentCourseLink> studentCourseList = new LinkedList<StudentCourseLink>();
	List<Course> courses = null;
	List<Student> students = null;
	private DateComparator dtComparator = new DateComparator();
	
	public StudentCourseList() {
	}
	
	protected List<Course> getCourseList() {
		if (courses==null) {
			courses = new LinkedList<Course>();
			for (StudentCourseLink link:studentCourseList) {
				Course course = link.getCourse();
				if (!courses.contains(course)){
					courses.add(course);
				}
			}
		}
		return courses;
	}
	
	protected List<Student> getStudentList() {
		if (students==null) {
			students = new LinkedList<Student>();
			for (StudentCourseLink link:studentCourseList) {
				Student student = link.getStudent();
				if (!students.contains(student)){
					students.add(student);
				}
			}
		}
		return students;
	}
	
	public StudentCourseLink[] toArray() {
		StudentCourseLink[] linkArray={};
		return studentCourseList.toArray(linkArray);
	}
	
	public Student[] getStudents() {
		Student[] studentArray={};
		return getStudentList().toArray(studentArray);
	}
	
	public Course[] getCourses() {
		Course[] courseArray={};
		return getCourseList().toArray(courseArray);
	}
	
	//courses that student are currently taking
	//course starts before now and ends after now
	public Course[] getCurrentCourses() {
		Course[] currentCourses = {};
		Date now = DateHelper.getToday();
		List<Course> coursesList = new ArrayList<Course>();
		for (Course course : getCourseList()) {
			if (course.isStartsBefore(now) && course.isEndsAfter(now)){
					coursesList.add(course);
				}
		}

		return coursesList.toArray(currentCourses);
	}
	
	/* 
	 * return courses that are within the startDate and endDate includes both bounds
	 * if the bound is null, assume there is no bound
	 */
	public Course[] getCoursesByDateRange(Date startDate, Date endDate) {
		Course[] coursesInRange = {};
		List<Course> coursesList = new ArrayList<Course>();

		boolean chkStart = (startDate != null);
		boolean chkEnd = (endDate != null);

		for (Course course : getCourseList()) {
			boolean inRange = true;
			if (chkStart) {
				if (course.getStartDate() == null) {
					inRange = false;
				} else {
					inRange = (dtComparator.compare(startDate, course.getStartDate()) < 0);
				}
			}
			if (inRange && chkEnd) {
				if (course.getEndDate() == null) {
					inRange = false;
				} else {
					inRange = (dtComparator.compare(endDate, course.getEndDate()) <= 0);
				}
			}
			if (inRange) {
				coursesList.add(course);
			}
		}

		coursesInRange = coursesList.toArray(coursesInRange);
		return coursesInRange;
	}

	public Course[] getFutureCourses() {
		Date tomorrow = DateHelper.getDateFromToday(1);
		return getCoursesByDateRange(tomorrow, null);
	}
	
	public Course[] getPastCourses() {
		Date yesterday = DateHelper.getDateFromToday(-1);
		return getCoursesByDateRange(null, yesterday);
	}
	
	public boolean contains(Course course){
		return getCourseList().contains(course);
	}

	public boolean contains(Student student){
		return getStudentList().contains(student);
	}

	public boolean contains(StudentCourseLink link){
		return studentCourseList.contains(link);
	}

	public boolean add(Student student, Course course){
		resetCacheLists();
		StudentCourseLink link = new StudentCourseLink(student, course);
		return studentCourseList.add(link);
	}
	
	public boolean remove(StudentCourseLink link){
		resetCacheLists();
		return studentCourseList.remove(link);
	}
	
	private void resetCacheLists() {
		courses = null;
		students=null;		
	}
}
